package com.lyh.system.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lyh.common.core.domain.BaseEntity;
import com.lyh.common.core.domain.entity.SysUser;
import com.lyh.common.enums.*;
import com.lyh.common.utils.DateUtils;
import com.lyh.common.utils.SecurityUtils;
import com.lyh.system.domain.*;
import com.lyh.system.domain.req.MemberBatchPurchasAuditReq;
import com.lyh.system.domain.req.MemberPurchasAuditReq;
import com.lyh.system.domain.req.MemberPurchaseInfoPageReq;
import com.lyh.system.domain.resp.MemberPurchaseAllInfoResp;
import com.lyh.system.domain.resp.MemberPurchaseInfoResp;
import com.lyh.system.domain.vo.OneDayOnceReserveVo;
import com.lyh.system.domain.vo.ReserveRecordVo;
import com.lyh.system.domain.vo.ReserveVo;
import com.lyh.system.mapper.*;
import com.lyh.system.service.IAssetService;
import com.lyh.system.service.IMemberPurchaseInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.lyh.common.enums.RebateRuleEnum.SAME_LEVEL_02;

/**
 * 用户预约报单信息Service业务层处理
 *
 * @author ruoyi
 * @date 2023-04-27
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class MemberPurchaseInfoServiceImpl implements IMemberPurchaseInfoService {
    @Autowired
    private MemberPurchaseInfoMapper memberPurchaseInfoMapper;

    @Autowired
    private AssetMapper assetMapper;

    @Autowired
    private IAssetService assetService;

    @Autowired
    private AssetEvidenceMapper assetEvidenceMapper;

    @Autowired
    private SysAreaOrderMapper sysAreaOrderMapper;

    @Autowired
    private OperationInfoMapper operationInfoMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysRelationValueMapper relationValueMapper;

    @Autowired
    private UserRebatesMapper userRebatesMapper;


    /**
     * 查询用户预约报单信息
     *
     * @param id 用户预约报单信息主键
     * @return 用户预约报单信息
     */
    @Override
    public MemberPurchaseInfo selectMemberPurchaseInfoById(Long id) {
        return memberPurchaseInfoMapper.selectMemberPurchaseInfoById(id);
    }

    /**
     * 查询用户预约报单信息列表
     *
     * @param memberPurchaseInfo 用户预约报单信息
     * @return 用户预约报单信息
     */
    @Override
    public List<MemberPurchaseInfo> selectMemberPurchaseInfoList(MemberPurchaseInfo memberPurchaseInfo) {
        return memberPurchaseInfoMapper.selectMemberPurchaseInfoList(memberPurchaseInfo);
    }

    @Override
    public List<MemberPurchaseInfoResp> selectMemberPurchaseUserInfoList(MemberPurchaseInfoPageReq req) {
        return memberPurchaseInfoMapper.selectMemberPurchaseUserInfoList(req);
    }


    /**
     * 新增用户预约报单信息
     *
     * @param memberPurchaseInfo 用户预约报单信息
     * @return 结果
     */
    @Override
    public int insertMemberPurchaseInfo(MemberPurchaseInfo memberPurchaseInfo) {
        memberPurchaseInfo.setCreateTime(DateUtils.getNowDate());
        return memberPurchaseInfoMapper.insertMemberPurchaseInfo(memberPurchaseInfo);
    }

    /**
     * 修改用户预约报单信息
     *
     * @param memberPurchaseInfo 用户预约报单信息
     * @return 结果
     */
    @Override
    public int updateMemberPurchaseInfo(MemberPurchaseInfo memberPurchaseInfo) {
        memberPurchaseInfo.setUpdateTime(DateUtils.getNowDate());
        return memberPurchaseInfoMapper.updateMemberPurchaseInfo(memberPurchaseInfo);
    }

    /**
     * 批量删除用户预约报单信息
     *
     * @param ids 需要删除的用户预约报单信息主键
     * @return 结果
     */
    @Override
    public int deleteMemberPurchaseInfoByIds(Long[] ids) {
        return memberPurchaseInfoMapper.deleteMemberPurchaseInfoByIds(ids);
    }

    /**
     * 删除用户预约报单信息信息
     *
     * @param id 用户预约报单信息主键
     * @return 结果
     */
    @Override
    public int deleteMemberPurchaseInfoById(Long id) {
        return memberPurchaseInfoMapper.deleteMemberPurchaseInfoById(id);
    }

    @Override
    public List<MemberPurchaseInfo> selectPurchaseInfoByMemberId(Long memberId) {
        return memberPurchaseInfoMapper.selectPurchaseInfoByMemberId(memberId);
    }

    @Override
    public String reservation(Long memberId, Long evidenceNum) {
        return null;
    }

    /**
     * 预约报单
     */
    @Override
    public void reserve(List<ReserveVo> reserves) {
        Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        if (hour >= 10 && hour < 12) {
            throw new RuntimeException("每天10:00到12:00不能预约，其余时间都可以预约!");
        }
        //当前登录人
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Asset asset = assetMapper.selectAssetByUserId(user.getUserId());
        BigDecimal allAssetEvidence = new BigDecimal(0);
        BigDecimal allConsumerCoupon = new BigDecimal(0);
        //消费券消耗比例
        SysRelationValue sysRelationValue = relationValueMapper.selectOne(new LambdaQueryWrapper<SysRelationValue>()
                .eq(SysRelationValue::getBusinessId, "BDFYSZ_MEMBER")
                .eq(SysRelationValue::getCode, "Immediately"));
        for (ReserveVo reserve : reserves) {
            AssetEvidence assetEvidence = assetEvidenceMapper.selectById(reserve.getEvidenceId());
            OneDayOnceReserveVo onceReserveVo = new OneDayOnceReserveVo();
            onceReserveVo.setUserId(user.getUserId());
            onceReserveVo.setArea(assetEvidence.getArea());
            onceReserveVo.setTimeInterval(reserve.getTimeInterval());
            onceReserveVo.setNum(assetEvidence.getNum());
            /** time 0 代表当前时间没有超过24点，查询今天10点半到现在数据 ，1 表示当前时间大于24点，查询昨天上午10点半到现在的数据 */
            if (hour >= 10) {
                onceReserveVo.setTime(0);
            } else {
                onceReserveVo.setTime(1);
            }

            //  每天预约一次
            List<MemberPurchaseInfo> memberPurchaseInfos = memberPurchaseInfoMapper.oneDayOnceReserve(onceReserveVo);
            if (memberPurchaseInfos != null && memberPurchaseInfos.size() > 0) {
                throw new RuntimeException("您已预约，无须重复预约，请明天继续参与!");
            }

            allAssetEvidence = allAssetEvidence.add(assetEvidence.getNum());
            Integer intervalTime = reserve.getTimeInterval();
            BigDecimal bigDecimal = new BigDecimal(intervalTime).multiply(assetEvidence.getNum()).multiply(new BigDecimal(sysRelationValue.getValue()).multiply(new BigDecimal(0.01)));
            allConsumerCoupon = allConsumerCoupon.add(bigDecimal);
        }
        if (asset.getConsumerCouponNum() == null || asset.getAssetEvidenceNum() == null
                || asset.getAssetEvidenceNum().compareTo(allAssetEvidence) < 0 || asset.getConsumerCouponNum().compareTo(allConsumerCoupon) < 0) {
            throw new RuntimeException("资产通证或消费券不足，无法预约！");
        }

        asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().subtract(allAssetEvidence));
        asset.setConsumerCouponNum(asset.getConsumerCouponNum().subtract(allConsumerCoupon));
        assetMapper.updateById(asset);

        for (ReserveVo reserve : reserves) {
            AssetEvidence assetEvidence = assetEvidenceMapper.selectById(reserve.getEvidenceId());
            Integer intervalTime = reserve.getTimeInterval();
            BigDecimal bigDecimal = new BigDecimal(intervalTime).multiply(assetEvidence.getNum()).multiply(new BigDecimal(sysRelationValue.getValue()).multiply(new BigDecimal(0.01)));

            MemberPurchaseInfo mpi = new MemberPurchaseInfo();
            mpi.setTimeInterval(intervalTime);
            c.setTime(new Date());

            //todo 注释掉 lzl
//            if (hour >= 12) {
//                c.set(Calendar.DATE, c.get(Calendar.DATE) + intervalTime + 1);
//            } else {
                c.set(Calendar.DATE, c.get(Calendar.DATE) + intervalTime);
//            }
            mpi.setIntervalNextTime(DateUtils.parseDateToStr("yyyy-MM-dd HH", c.getTime()));
            mpi.setStatus(PurchaseStatusEnum.WAIT_AUDIT.getCode());

            //预估收益
            QueryWrapper<SysAreaOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("area_type", assetEvidence.getArea());
            SysAreaOrder areaOrder = sysAreaOrderMapper.selectOne(queryWrapper);
            BigDecimal incomeRate = new BigDecimal("1");
            if (intervalTime == 2) {
                if (areaOrder.getTwoNum() != null) {
                    incomeRate = incomeRate.multiply(areaOrder.getTwoNum()).multiply(new BigDecimal("0.01"));
                }
            } else if (intervalTime == 3) {
                if (areaOrder.getThirdNum() != null) {
                    incomeRate = incomeRate.multiply(areaOrder.getThirdNum()).multiply(new BigDecimal("0.01"));
                }
            } else if (intervalTime == 5) {
                if (areaOrder.getFiveNum() != null) {
                    incomeRate = incomeRate.multiply(areaOrder.getFiveNum()).multiply(new BigDecimal("0.01"));
                }
            } else if (intervalTime == 7) {
                if (areaOrder.getSevenNum() != null) {
                    incomeRate = incomeRate.multiply(areaOrder.getSevenNum()).multiply(new BigDecimal("0.01"));
                }
            }

            //收益金额
            BigDecimal multiply = assetEvidence.getNum().multiply(incomeRate);

            mpi.setMaybeIncome(multiply);
            mpi.setUserId(user.getUserId());
            mpi.setAssetEvidenceId(assetEvidence.getId());
            mpi.setAssetEvidenceNum(assetEvidence.getNum());
            mpi.setConsumerCouponNum(bigDecimal);
            mpi.setResidueAssetEvidence(bigDecimal);
            memberPurchaseInfoMapper.insert(mpi);

        }

        //添加收支记录(资产通证)
        OperationInfo oi = new OperationInfo();
        oi.setUserId(user.getUserId());
        oi.setType(OperationTypeEnum.ASSET_EVIDENCE.name());
        oi.setStatus(OperationStatusEnum.EXPENSE.name());
        oi.setOperationTime(new Date());
        oi.setPrice(allAssetEvidence);
        oi.setOrigin(OperationOriginEnum.RESERVE_EVIDENCE.name());
        operationInfoMapper.insert(oi);

        //添加收支记录(消费券)
        OperationInfo oi1 = new OperationInfo();
        oi1.setStatus(OperationStatusEnum.EXPENSE.name());
        oi1.setOperationTime(new Date());
        oi1.setUserId(user.getUserId());
        oi1.setType(OperationTypeEnum.CONSUMER_COUPON.name());
        oi1.setPrice(allConsumerCoupon);
        oi1.setOrigin(OperationOriginEnum.RESERVE_EVIDENCE.name());
        operationInfoMapper.insert(oi1);

    }

    @Override
    public void EndChangeReserveRebatesRule(SysUser parentUser, BigDecimal num, Boolean lastSame, MemberPurchaseInfo memberPurchaseInfo, SysUser lastUser, Boolean isFirst) {

        BigDecimal day = new BigDecimal(memberPurchaseInfo.getTimeInterval());

        //立即到账比例
        SysRelationValue relationValue = relationValueMapper.selectOne(new LambdaQueryWrapper<SysRelationValue>()
                .eq(SysRelationValue::getCode, "Immediately")
                .eq(SysRelationValue::getBusinessId, "BDFYSZ"));
        BigDecimal immediately = new BigDecimal(relationValue.getValue()).multiply(new BigDecimal("0.01"));

        if (parentUser == null || parentUser.getMemberLeve() == null) {
            return;
        }
        if (lastUser.getMemberLeve() != null) {
            if (lastSame && lastUser.getMemberLeve() == 5) {
                return;
            }
            if (parentUser.getMemberLeve().equals(lastUser.getMemberLeve()) && parentUser.getMemberLeve() != 0) {
                if (!lastSame) {
                    List<MemberPurchaseInfo> memberPurchaseInfos = memberPurchaseInfoMapper.getByIdTwoStatus(parentUser.getUserId(), 0, 1);
                    if (memberPurchaseInfos != null && memberPurchaseInfos.size() > 0) {
                    BigDecimal bigDecimal;
                    if (isFirst) {
                        bigDecimal = getRatioByMemberLevel(parentUser.getMemberLeve()).multiply(immediately).multiply(num).multiply(day);
                    } else {
                        bigDecimal = num.multiply(new BigDecimal("0.00001")).multiply(immediately).multiply(day);
                        lastSame = true;
                    }

                    //添加收支记录(资产通证)
                    OperationInfo oi = new OperationInfo();
                    oi.setUserId(parentUser.getUserId());
                    oi.setType(OperationTypeEnum.ASSET_EVIDENCE.name());
                    oi.setStatus(OperationStatusEnum.INCOME.name());
                    oi.setOperationTime(new Date());
                    oi.setOrigin(OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name());
                    UserRebates userRebates = new UserRebates();
                    userRebates.setRebateTime(new Date());
                    userRebates.setMemberPurchaseInfoId(memberPurchaseInfo.getId());
                    Asset asset = assetMapper.selectAssetByUserId(parentUser.getUserId());

                    if (memberPurchaseInfo.getResidueAssetEvidence().subtract(bigDecimal).compareTo(new BigDecimal(0)) < 0) {
                        if (asset != null && asset.getEquityLimit() != null && asset.getEquityLimit().compareTo(new BigDecimal("0")) >= 0) {
                            BigDecimal subtract = asset.getEquityLimit().subtract(memberPurchaseInfo.getResidueAssetEvidence());

                            userRebates.setResidueRebate(new BigDecimal(0));

                            if (subtract.compareTo(new BigDecimal(0)) >= 0) {
                                memberPurchaseInfo.setResidueAssetEvidence(new BigDecimal(0));
                                oi.setPrice(memberPurchaseInfo.getResidueAssetEvidence());
                                asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(memberPurchaseInfo.getResidueAssetEvidence()));
                                asset.setEquityLimit(subtract);

                                //记录
                                assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                        OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), memberPurchaseInfo.getResidueAssetEvidence());
                            } else {
                                memberPurchaseInfo.setResidueAssetEvidence(memberPurchaseInfo.getResidueAssetEvidence().subtract(asset.getEquityLimit()));
                                oi.setPrice(asset.getEquityLimit());
                                asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(asset.getEquityLimit()));
                                //记录
                                assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                        OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), asset.getEquityLimit());
                                asset.setEquityLimit(new BigDecimal(0));
                            }

                        }

                    } else {

                        if (asset != null && asset.getEquityLimit() != null && asset.getEquityLimit().compareTo(new BigDecimal("0")) >= 0) {
                            BigDecimal subtract = asset.getEquityLimit().subtract(bigDecimal);

                            if (subtract.compareTo(new BigDecimal(0)) >= 0) {

                                BigDecimal residueRebate;
                                if (isFirst) {
                                    residueRebate = getRatioByMemberLevel(parentUser.getMemberLeve()).multiply(num).subtract(bigDecimal);
                                } else {
                                    residueRebate = num.multiply(new BigDecimal("0.00001")).subtract(bigDecimal);
                                }

                                oi.setPrice(bigDecimal);
                                asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(bigDecimal));
                                asset.setEquityLimit(subtract);

                                //记录
                                assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                        OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), bigDecimal);

                                if (asset.getEquityLimit().subtract(residueRebate).compareTo(new BigDecimal(0)) >= 0) {
                                    asset.setEquityLimit(subtract.subtract(residueRebate));
                                    //记录
                                    assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                            OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), residueRebate);
                                    userRebates.setResidueRebate(residueRebate);
                                } else {
                                    //记录
                                    assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                            OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), asset.getEquityLimit());
                                    asset.setEquityLimit(new BigDecimal(0));
                                    userRebates.setResidueRebate(asset.getEquityLimit());
                                }
                                memberPurchaseInfo.setResidueAssetEvidence(memberPurchaseInfo.getResidueAssetEvidence().subtract(bigDecimal));
                            } else {
                                oi.setPrice(asset.getEquityLimit());
                                userRebates.setResidueRebate(new BigDecimal(0));
                                asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(asset.getEquityLimit()));
                                //记录
                                assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                        OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), asset.getEquityLimit());
                                asset.setEquityLimit(new BigDecimal(0));
                                memberPurchaseInfo.setResidueAssetEvidence(memberPurchaseInfo.getResidueAssetEvidence().subtract(asset.getEquityLimit()));
                            }

                        }

                    }

                    userRebates.setAssetEvidenceNum(num);
                    userRebates.setRebateRule(SAME_LEVEL_02);
                    userRebates.setUserId(parentUser.getUserId());
                    if (userRebates.getResidueRebate().compareTo(new BigDecimal(0)) != 0) {
                        userRebatesMapper.insert(userRebates);
                    }

                    if (oi.getPrice().compareTo(new BigDecimal(0)) != 0) {
                        operationInfoMapper.insert(oi);
                    }

                    assetMapper.updateById(asset);
                    memberPurchaseInfoMapper.updateById(memberPurchaseInfo);
                    }
                    lastUser = parentUser;
                }
            }

            if (parentUser.getMemberLeve() > lastUser.getMemberLeve()) {

                List<MemberPurchaseInfo> memberPurchaseInfos = memberPurchaseInfoMapper.getByIdTwoStatus(parentUser.getUserId(), 0, 1);
                if (memberPurchaseInfos != null && memberPurchaseInfos.size() > 0) {
                UserRebates userRebates = new UserRebates();
                BigDecimal ratioByMemberLevel = new BigDecimal("0");

                if (!isFirst) {
                    if (lastUser.getMemberLeve() != null && lastUser.getMemberLeve() != 0) {
                        ratioByMemberLevel = getRatioByMemberLevel(lastUser.getMemberLeve());
                    }
                }
                BigDecimal multiply = getRatioByMemberLevel(parentUser.getMemberLeve()).subtract(ratioByMemberLevel).multiply(immediately).multiply(num).multiply(day);

                userRebates.setRebateRule(RebateRuleEnum.HIGH_LEVEL);
                userRebates.setMemberPurchaseInfoId(memberPurchaseInfo.getId());
                Asset asset = assetMapper.selectAssetByUserId(parentUser.getUserId());

                //添加收支记录(资产通证)
                OperationInfo oi = new OperationInfo();
                oi.setUserId(parentUser.getUserId());
                oi.setType(OperationTypeEnum.ASSET_EVIDENCE.name());
                oi.setStatus(OperationStatusEnum.INCOME.name());
                oi.setOperationTime(new Date());
                oi.setOrigin(OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name());


                if (memberPurchaseInfo.getResidueAssetEvidence().subtract(multiply).compareTo(new BigDecimal(0)) < 0) {

                    if (asset != null && asset.getEquityLimit() != null && asset.getEquityLimit().compareTo(new BigDecimal("0")) >= 0) {
                        BigDecimal subtract = asset.getEquityLimit().subtract(memberPurchaseInfo.getResidueAssetEvidence());

                        userRebates.setResidueRebate(new BigDecimal(0));

                        if (subtract.compareTo(new BigDecimal(0)) >= 0) {
                            memberPurchaseInfo.setResidueAssetEvidence(new BigDecimal(0));
                            oi.setPrice(memberPurchaseInfo.getResidueAssetEvidence());
                            asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(memberPurchaseInfo.getResidueAssetEvidence()));
                            asset.setEquityLimit(subtract);
                            //记录
                            assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                    OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), memberPurchaseInfo.getResidueAssetEvidence());

                        } else {
                            oi.setPrice(asset.getEquityLimit());
                            asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(asset.getEquityLimit()));
                            //记录
                            assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                    OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), asset.getEquityLimit());
                            asset.setEquityLimit(new BigDecimal(0));
                            memberPurchaseInfo.setResidueAssetEvidence(memberPurchaseInfo.getResidueAssetEvidence().subtract(asset.getEquityLimit()));
                        }
                    }

                } else {

                    BigDecimal ratioLevel = new BigDecimal("0");
                    if (!isFirst && lastUser.getMemberLeve() != null && lastUser.getMemberLeve() != 0) {
                        ratioLevel = getRatioByMemberLevel(lastUser.getMemberLeve());
                    }

                    if (asset != null && asset.getEquityLimit() != null && asset.getEquityLimit().compareTo(new BigDecimal("0")) >= 0) {
                        BigDecimal subtract = asset.getEquityLimit().subtract(multiply);

                        if (subtract.compareTo(new BigDecimal(0)) >= 0) {
                            BigDecimal residueRebate = num.multiply(getRatioByMemberLevel(parentUser.getMemberLeve()).subtract(ratioLevel)).subtract(multiply);
                            oi.setPrice(multiply);
                            asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(multiply));
                            if (asset.getEquityLimit().subtract(residueRebate).compareTo(new BigDecimal(0)) >= 0) {
                                asset.setEquityLimit(subtract.subtract(residueRebate));
                                //记录
                                assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                        OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), residueRebate);
                                userRebates.setResidueRebate(residueRebate);
                            } else {
                                //记录
                                assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                        OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), asset.getEquityLimit());
                                asset.setEquityLimit(new BigDecimal(0));
                                userRebates.setResidueRebate(asset.getEquityLimit());
                            }
                            memberPurchaseInfo.setResidueAssetEvidence(memberPurchaseInfo.getResidueAssetEvidence().subtract(multiply));
                        } else {
                            //记录
                            assetService.addOperationInfo(parentUser.getUserId(), OperationTypeEnum.EQUITY_LIMIT.name(), OperationStatusEnum.EXPENSE.name(),
                                    OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name(), asset.getEquityLimit());
                            oi.setPrice(asset.getEquityLimit());
                            userRebates.setResidueRebate(new BigDecimal(0));
                            asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(asset.getEquityLimit()));
                            asset.setEquityLimit(new BigDecimal(0));
                            memberPurchaseInfo.setResidueAssetEvidence(memberPurchaseInfo.getResidueAssetEvidence().subtract(asset.getEquityLimit()));
                        }
                    }
                }

                userRebates.setAssetEvidenceNum(num);
                userRebates.setUserId(parentUser.getUserId());
                userRebates.setRebateTime(new Date());
                userRebates.setLowUserId(lastUser.getUserId());
                if (userRebates.getResidueRebate().compareTo(new BigDecimal(0)) != 0) {
                    userRebatesMapper.insert(userRebates);
                }
                if (oi.getPrice().compareTo(new BigDecimal(0)) != 0) {
                    operationInfoMapper.insert(oi);
                }
                assetMapper.updateById(asset);
                memberPurchaseInfoMapper.updateById(memberPurchaseInfo);

                lastUser = parentUser;
                lastSame = false;
            }
            }
            SysUser sysUser = sysUserMapper.selectById(parentUser.getParentId());
            EndChangeReserveRebatesRule(sysUser, num, lastSame, memberPurchaseInfo, lastUser, false);
        }
    }

    @Override
    public void allUserReserve(SysUser parentUser, BigDecimal num, MemberPurchaseInfo memberPurchaseInfo, BigDecimal bili, int number) {

        //消费券消耗比例
        SysRelationValue sysRelationValue = relationValueMapper.selectOne(new LambdaQueryWrapper<SysRelationValue>()
                .eq(SysRelationValue::getBusinessId, "BDFYSZ_MEMBER")
                .eq(SysRelationValue::getCode, "Immediately"));

        //对应场次基础比率 非末级
        SysRelationValue sysRelationValue2 = relationValueMapper.selectOne(new LambdaQueryWrapper<SysRelationValue>()
                .eq(SysRelationValue::getBusinessId, "DYCCJCBL_MEMBER")
                .eq(SysRelationValue::getCode, "Immediately"));

        //对应场次基础比率 末级
        SysRelationValue sysRelationValue3 = relationValueMapper.selectOne(new LambdaQueryWrapper<SysRelationValue>()
                .eq(SysRelationValue::getBusinessId, "DYCCJCBLMJ_MEMBER")
                .eq(SysRelationValue::getCode, "Immediately"));

        BigDecimal sumVIPRebates = new BigDecimal(memberPurchaseInfo.getTimeInterval()).multiply(num).multiply(new BigDecimal(sysRelationValue.getValue()).multiply(new BigDecimal(0.01)));

        if (parentUser.getRebatesFlag() == 1) {
            //8级
            if (number == 0) {
                BigDecimal lastMultiply = num.multiply(new BigDecimal("0.01")).multiply(new BigDecimal(sysRelationValue3.getValue())).multiply(new BigDecimal(memberPurchaseInfo.getTimeInterval()));
                BigDecimal add = lastMultiply.subtract(sumVIPRebates).add(memberPurchaseInfo.getResidueAssetEvidence());
                //添加收支记录
                OperationInfo oi = new OperationInfo();
                oi.setUserId(parentUser.getUserId());
                oi.setType(OperationTypeEnum.ASSET_EVIDENCE.name());
                oi.setStatus(OperationStatusEnum.INCOME.name());
                oi.setOperationTime(new Date());
                oi.setOrigin(OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name());
                oi.setPrice(add);
                if (oi.getPrice().compareTo(new BigDecimal(0)) > 0) {
                    operationInfoMapper.insert(oi);
                }

                Asset asset = assetMapper.selectAssetByUserId(parentUser.getUserId());
                asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(add));
                if (add.compareTo(new BigDecimal(0)) > 0) {
                    assetMapper.updateById(asset);
                }

                bili = parentUser.getRebatesRate() == null ? new BigDecimal(0) : parentUser.getRebatesRate();
            } else {
                BigDecimal multiply = num.multiply(new BigDecimal("0.01")).multiply(new BigDecimal(sysRelationValue2.getValue())).multiply(new BigDecimal(memberPurchaseInfo.getTimeInterval()));
                BigDecimal rebatesRate = parentUser.getRebatesRate();
                if (bili != null) {
                    rebatesRate = rebatesRate.subtract(bili).multiply(new BigDecimal("0.01"));
                } else {
                    rebatesRate = rebatesRate.multiply(new BigDecimal("0.01"));
                }
                BigDecimal bigDecimal = multiply.multiply(rebatesRate);

                //顶级账号
                if (number == 8) {
                    bigDecimal = multiply;
                }

                //添加收支记录
                OperationInfo oi = new OperationInfo();
                oi.setUserId(parentUser.getUserId());
                oi.setType(OperationTypeEnum.ASSET_EVIDENCE.name());
                oi.setStatus(OperationStatusEnum.INCOME.name());
                oi.setOperationTime(new Date());
                oi.setOrigin(OperationOriginEnum.RESERVE_EVIDENCE_INCOME.name());
                oi.setPrice(bigDecimal);
                if (oi.getPrice().compareTo(new BigDecimal(0)) > 0) {
                    operationInfoMapper.insert(oi);
                }

                Asset asset = assetMapper.selectAssetByUserId(parentUser.getUserId());
                asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(bigDecimal));

                if (bigDecimal.compareTo(new BigDecimal(0)) > 0) {
                    assetMapper.updateById(asset);
                }

                bili = parentUser.getRebatesRate() == null ? new BigDecimal(0) : parentUser.getRebatesRate();
            }
            number++;
        }

        SysUser grandUser = sysUserMapper.selectById(parentUser.getParentId());
        if (grandUser != null) {
            allUserReserve(grandUser, num, memberPurchaseInfo, bili, number);
        }
    }


    @Override
    public BigDecimal getRatioByMemberLevel(int level) {
        QueryWrapper<SysRelationValue> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("business_id", "BDFYSZ_MEMBER");
        List<SysRelationValue> relationValues = relationValueMapper.selectList(queryWrapper);
        Map<String, String> map = relationValues.stream().collect(Collectors.toMap(SysRelationValue::getCode, SysRelationValue::getValue));
        String number;
        switch (level) {
            case 1:
                number = map.get("EveryV1") == null ? "0" : map.get("EveryV1");
                break;
            case 2:
                number = map.get("EveryV2") == null ? "0" : map.get("EveryV2");
                break;
            case 3:
                number = map.get("EveryV3") == null ? "0" : map.get("EveryV3");
                break;
            case 4:
                number = map.get("EveryV4") == null ? "0" : map.get("EveryV4");
                break;
            case 5:
                number = map.get("EveryV5") == null ? "0" : map.get("EveryV5");
                break;
            default:
                number = "0.00";
        }
        return new BigDecimal(number).multiply(new BigDecimal("0.01"));
    }

    @Override
    public MemberPurchaseAllInfoResp webAllNum(MemberPurchaseInfoPageReq req) {
        //取总数
        Integer integer = memberPurchaseInfoMapper.selectCount(new LambdaQueryWrapper<MemberPurchaseInfo>());
        Integer integer1 = memberPurchaseInfoMapper.selectCount(new LambdaQueryWrapper<MemberPurchaseInfo>()
                .likeRight(BaseEntity::getCreateTime,
                        DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.getNowDate())
                ));

        Integer integer2 = memberPurchaseInfoMapper.selectCount(new LambdaQueryWrapper<MemberPurchaseInfo>()
                .eq(MemberPurchaseInfo::getStatus, PurchaseStatusEnum.WAIT_AUDIT.getCode()));
        Integer integer3 = memberPurchaseInfoMapper.selectCount(new LambdaQueryWrapper<MemberPurchaseInfo>()
                .eq(MemberPurchaseInfo::getStatus, PurchaseStatusEnum.AUDIT.getCode()));

        Integer integer4 = memberPurchaseInfoMapper.selectCount(new LambdaQueryWrapper<MemberPurchaseInfo>()
                .eq(MemberPurchaseInfo::getStatus, PurchaseStatusEnum.PURCHASE_FAIL.getCode()));

        MemberPurchaseAllInfoResp resp = new MemberPurchaseAllInfoResp();
        resp.setAllNum(integer);
        resp.setWaitNum(integer2);
        resp.setTodayNum(integer1);
        resp.setAuditNum(integer3);
        resp.setFailNum(integer4);
        //按日期查按金额查场次金额
        List<MemberPurchaseInfoResp> resps = memberPurchaseInfoMapper.selectMemberPurchaseUserInfoAll(req);
        if(resps!=null && resps.size()>0){
            resps.stream().forEach(c->{
                if(TimeIntervalEnum.getEnum(c.getTimeInterval())!=null){
                    c.setTimeIntervalName( TimeIntervalEnum.getEnum(c.getTimeInterval()).getName());
                }
            });
        }
        resp.setList(resps);
        return resp;
    }

    @Override
    public int audit(MemberPurchasAuditReq req) {
        MemberPurchaseInfo info = memberPurchaseInfoMapper.selectById(req.getId());
        info.setStatus(req.getPassFlag() == 1 ? PurchaseStatusEnum.AUDIT.getCode() : PurchaseStatusEnum.PURCHASE_FAIL.getCode());
        info.setAuditId(SecurityUtils.getLoginUser().getUserId());
        info.setAuditTime(new Date());//审核时间
        info.setUpdateBy(SecurityUtils.getLoginUser().getUsername());

        //预约失败返回资产通证和消费券
        if (info.getStatus() == 2) {
            System.out.println("<===============手动拒绝预约=================>");

            Asset asset = assetMapper.selectAssetByUserId(info.getUserId());
            asset.setAssetEvidenceNum(asset.getAssetEvidenceNum().add(info.getAssetEvidenceNum()));
            asset.setConsumerCouponNum(asset.getConsumerCouponNum().add(info.getConsumerCouponNum()));
            asset.setUpdateTime(new Date());
            assetMapper.updateById(asset);

            //添加收支记录(资产通证)
            OperationInfo oi = new OperationInfo();
            oi.setUserId(info.getUserId());
            oi.setType(OperationTypeEnum.ASSET_EVIDENCE.name());
            oi.setStatus(OperationStatusEnum.INCOME.name());
            oi.setOperationTime(new Date());
            oi.setPrice(info.getAssetEvidenceNum());
            oi.setOrigin(OperationOriginEnum.RESERVE_EVIDENCE.name());
            operationInfoMapper.insert(oi);

            //添加收支记录(消费券)
            OperationInfo oi1 = new OperationInfo();
            oi1.setUserId(info.getUserId());
            oi1.setType(OperationTypeEnum.ASSET_EVIDENCE.name());
            oi1.setStatus(OperationStatusEnum.INCOME.name());
            oi1.setOperationTime(new Date());
            oi1.setType(OperationTypeEnum.CONSUMER_COUPON.name());
            oi1.setPrice(info.getConsumerCouponNum());
            oi1.setOrigin(OperationOriginEnum.RESERVE_EVIDENCE.name());
            operationInfoMapper.insert(oi1);
        }
        return memberPurchaseInfoMapper.updateById(info);
    }


    @Override
    public int batchAudit(MemberBatchPurchasAuditReq req) {

        List<MemberPurchaseInfo> memberPurchaseInfos = null;
        switch (req.getBatchType()) {
            case 1://随机1000人预约成功
                memberPurchaseInfos = memberPurchaseInfoMapper.selectList(new LambdaQueryWrapper<MemberPurchaseInfo>()
                        .eq(MemberPurchaseInfo::getStatus, PurchaseStatusEnum.WAIT_AUDIT.getCode())
                        .last("order by RAND() limit " + req.getPersonNum()));
                break;

            case 2://预约时间早优选有原则
                memberPurchaseInfos = memberPurchaseInfoMapper.selectList(new LambdaQueryWrapper<MemberPurchaseInfo>()
                        .eq(MemberPurchaseInfo::getStatus, PurchaseStatusEnum.WAIT_AUDIT.getCode())
                        .orderByAsc(BaseEntity::getCreateTime)
                        .last("limit " + req.getPersonNum()));
                break;
            case 3://预约资金量大优先原则
                memberPurchaseInfos = memberPurchaseInfoMapper.selectList(new LambdaQueryWrapper<MemberPurchaseInfo>()
                        .eq(MemberPurchaseInfo::getStatus, PurchaseStatusEnum.WAIT_AUDIT.getCode())
                        .orderByDesc(MemberPurchaseInfo::getAssetEvidenceNum)
                        .last("limit " + req.getPersonNum()));
                break;

        }
        if (memberPurchaseInfos != null && memberPurchaseInfos.size() > 0) {
            MemberPurchaseInfo info = new MemberPurchaseInfo();
            info.setStatus(PurchaseStatusEnum.AUDIT.getCode());
            info.setAuditId(SecurityUtils.getLoginUser().getUserId());
            info.setAuditTime(new Date());
            memberPurchaseInfoMapper.update(info, new LambdaQueryWrapper<MemberPurchaseInfo>()
                    .in(MemberPurchaseInfo::getId, memberPurchaseInfos.stream().map(MemberPurchaseInfo::getId).collect(Collectors.toList())));

        }
        return 1;
    }

    @Override
    public List<ReserveRecordVo> getReserveRecord(Long userId) {
        return memberPurchaseInfoMapper.getReserveRecord(userId);
    }
}
